open StdLabels
open Gobject.Data
open GtkTree

let dirImg = "directory.png"
let fileImg = "file.png"
let pixBufFile = GdkPixbuf.from_file fileImg
let pixBufDir = GdkPixbuf.from_file dirImg
let hashtblFile = ref (Hashtbl.create 101)

let list_dir_files dir =
  let camlfiles = Str.regexp ".*.ml" in
  let cfiles = Str.regexp ".*.c$" in
  let textfiles = Str.regexp ".*.txt$" in
  let nofiles = Str.regexp ".*\\.+.*" in
  let makefile = Str.regexp_string "Makefile" in
  let fileList = Sys.readdir dir in
  let files = ref [] in
  let _ = print_endline (Sys.getcwd ()) in
  let _ = Array.sort (String.compare) fileList in
  Array.iter
    (fun file ->
      let path = Filename.concat dir file in
      if ((Sys.is_directory path) || ((Str.string_match cfiles file 0) 
              || (Str.string_match camlfiles file 0) 
              || (Str.string_match textfiles file 0) 
              || (not (Str.string_match nofiles file 0))
              || (Str.string_match makefile file 0) 
              ))
      then
      files := file:: !files)
    (fileList);
  !files

let dir1 = list_dir_files "."

let rec addHashFile = function
      [] -> ()
    | e::l -> Hashtbl.add !hashtblFile e ((Sys.getcwd ())^"/"^e); addHashFile l

let _ = addHashFile dir1

let toplevel = ref
    [
        ".", dir1;
    ]

let cols = new GTree.column_list
let name = cols#add string
let icon = cols#add (gobject_by_name "GdkPixbuf")

class tree_view scrollTree =
object(this)

val mutable model = GTree.tree_store cols

method private add_dir dir_name dir = 
      let row = model#append () in
      let set column = model#set ~row ~column in
      model#set ~row ~column:name dir_name;
      set icon pixBufDir;
      List.iter
        (fun n ->
          let row = model#append ~parent:row () in
          let set column = model#set ~row ~column in
          set name n;
          let path = Filename.concat dir_name n in
          if (Sys.is_directory path) then
          set icon pixBufDir
          else
          set icon pixBufFile
        ) dir
  
method private create_model =
  List.iter
    ( 
    fun (dir_name, dir) ->
    begin
      this#add_dir dir_name dir
    end
    ) 
  !toplevel;
  model

method private set_model = model <- this#create_model
method get_model = model
method get_colName = name

method createNewDir dir_name dir = 
    this#add_dir dir_name (list_dir_files dir)
 
method private add_columns ~(view : GTree.view) ~model =
 let renderer = GTree.cell_renderer_pixbuf [`XALIGN 0.] in
      let vc = GTree.view_column 
        ~title:"" 
        ~renderer:(renderer, ["pixbuf", icon] ) () in
      ignore(view#append_column vc);
     vc#set_sizing `FIXED;
     vc#set_fixed_width 100;
  let renderer = GTree.cell_renderer_text [`XALIGN 0.] in
  let vc = GTree.view_column 
    ~title:"File/Directory" 
    ~renderer:(renderer, ["text", name]) () in
  view#append_column vc


method getFullPath path = Hashtbl.find !hashtblFile path

method do_tree_store =
    this#set_model;
    let treeview = GTree.view 
    ~model:model 
    ~packing:scrollTree#add () in
  treeview#set_rules_hint true;
  treeview#selection#set_mode `MULTIPLE;
  ignore(treeview#selection#connect#after#changed ~callback:
    begin fun () ->
      prerr_endline "selection changed";
      List.iter treeview#selection#get_selected_rows ~f:
        (fun p -> prerr_endline (GtkTree.TreePath.to_string p));
    end);
    ignore(this#add_columns ~view:treeview ~model);
    treeview
    
end
